package com.topscomm.qem.service.impl;

import com.topscomm.basic.exception.ServiceException;
import com.topscomm.cbo.pojo.CboAttachmentEntity;
import com.topscomm.cbo.pojo.CboAttachmentTypeEntity;
import com.topscomm.cbo.service.ICboAttachmentService;
import com.topscomm.cbo.service.ICboAttachmentTypeService;
import com.topscomm.pub.util.*;
import com.topscomm.qem.service.FilePreviewService;
import com.topscomm.qem.util.GenerateExcelTemplateUtil;
import com.topscomm.qem.util.GeneratePPTTemplateUtil;
import com.topscomm.qem.util.GenerateWordTemplateUtil;
import com.topscomm.tap.common.ParameterCache;
import com.topscomm.tap.common.TapSystemConst;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.io.ZipInputStream;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.unzip.UnzipUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


@Service(value = "filePreviewServiceImpl")
@Scope("singleton")
public class FilePreviewServiceImpl implements FilePreviewService {
    @Autowired
    private ICboAttachmentService cboAttachmentService;
    @Autowired
    private ICboAttachmentTypeService cboAttachmentTypeService;

    /**
     * @Description: 转pdf后下载模板文件
     * @Author: mengmeng
     * @Date: 2021/8/16 14:14
     * @Version: 1.0
     */
    @Override
    public Map<String, Object> executeDownload(Map<String, Object> paraMap) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            // 附件对象
            StringBufferProxy sqlWhere = new StringBufferProxy();
            if (paraMap.containsKey("attachmentId")) {
                String attachmentId = ConvertUtil.convertToString(paraMap.get("attachmentId"));
                sqlWhere.appendLineSingle(" id={0}", attachmentId);
            } else {
                sqlWhere.appendLineSingle(" 1=1 ");
                if (paraMap.containsKey("sourcetype")) {
                    sqlWhere.appendLineSingle(" and sourcetype='{0}'",
                            ConvertUtil.convertToString(paraMap.get("sourcetype")));
                }
                if (paraMap.containsKey("sourceid")) {
                    sqlWhere.appendLineSingle(" and sourceid='{0}'",
                            ConvertUtil.convertToString(paraMap.get("sourceid")));
                }
            }
            Map<String, Object> queryMap = new HashMap<String, Object>();
            queryMap.put("whereSql", sqlWhere.toString());
            CboAttachmentEntity attachment = cboAttachmentService.getByte(queryMap);
            resultMap.put("attFileName", attachment.getDisplayname());
            // 存储配置
            CboAttachmentTypeEntity attachmentType = cboAttachmentTypeService
                    .queryById(ConvertUtil.convertToString(attachment.getAttachmenttypeid()));
            if (attachmentType == null) {
                throw new ServiceException("没有设置正确的配置参数！");
            }
            if (attachmentType.getStoretype().equals(TapSystemConst.TapAttachmentStoreType.FTP)) {
                downloadFtp(resultMap, paraMap, attachment, attachmentType);
            }
        } catch (Exception e) {
            throw new ServiceException(e);
        }
        return resultMap;
    }

    /**
     * @Description:    下载文件后转ftp
     * @Author:         mengmeng
     * @Date:           2021/8/19 9:57
     * @Version:        1.0
     */
    private void downloadFtp(Map<String, Object> resultMap, Map<String, Object> paraMap, CboAttachmentEntity attachment,
                             CboAttachmentTypeEntity attachmentType) {
        try {
            FTPProcessor ftpProcessor = null;
            ZipInputStream is = null;
            OutputStream os = null;
            String tempZipFilePath = null;
            String unZipFilePath = null;
            String tempZipDirectoryName = null;
            String uuid = UUID.randomUUID().toString();
            String property = System.getProperties().getProperty("file.separator");
            try {
                // 临时目录，用于解压缩文件
                tempZipDirectoryName = BaseUtil.getProjectPath() + "zip" + property + uuid;
                File tempZipDirectory = new File(tempZipDirectoryName);
                if (!tempZipDirectory.exists() && !tempZipDirectory.isDirectory()) {
                    tempZipDirectory.mkdirs();
                }
                // 打开FTP连接,下载并解压
                ftpProcessor = new FTPProcessor();
                ftpProcessor.connect(attachmentType.getFtppath(), attachmentType.getFtpserver(),
                        Integer.parseInt(attachmentType.getFtpport()), attachmentType.getFtpuser(),
                        attachmentType.getFtppwd());
                // Ftp文件路径
                String ftpFilePath = attachment.getSavepath() + attachment.getFilename();
                // Zip文件下载路径，下载Zip文件
                tempZipFilePath = tempZipDirectoryName + property + attachment.getFilename();
                ftpProcessor.download(ftpFilePath, tempZipFilePath);
                String displayName = attachment.getDisplayname();
                if (attachmentType.getCompresszip() == 0)// 不压缩
                {
                    resultMap.put("attFileName", displayName);
                    resultMap.put("attInputStream", FileUtil.convertFileToBytes(tempZipFilePath));
                } else {
                    // 解压
                    ZipFile zipFile = new ZipFile(tempZipFilePath);
                    zipFile.setFileNameCharset("GBK");
                    if (zipFile.isEncrypted()) {
                        zipFile.setPassword(attachment.getPwd());
                    }
                    List<FileHeader> fileHeaderList = zipFile.getFileHeaders();
                    FileHeader fileHeader = fileHeaderList.get(0);
                    if (fileHeader != null) {
                        unZipFilePath = tempZipDirectoryName + property + displayName;
                        File unZipFile = new File(unZipFilePath);
                        if (fileHeader.isDirectory()) {
                            unZipFile.mkdirs();
                        }
                        is = zipFile.getInputStream(fileHeader);
                        os = new FileOutputStream(unZipFile);
                        int readLen = -1;
                        byte[] buff = new byte[4096];
                        while ((readLen = is.read(buff)) != -1) {
                            os.write(buff, 0, readLen);
                        }
                        UnzipUtil.applyFileAttributes(fileHeader, unZipFile);
                        String extentionOfUnzipFile = FileUtil.getExtention(displayName);
                        String convertDisplayName = displayName.substring(0, displayName.indexOf(".")) + ".pdf";
                        String destDirectory = tempZipDirectoryName + property + convertDisplayName;
                        if (".docx".equals(extentionOfUnzipFile) || ".doc".equals(extentionOfUnzipFile) ) {
                            GenerateWordTemplateUtil.convertToPdf(unZipFilePath, destDirectory);
                        }
                        else if(".xlsx".equals(extentionOfUnzipFile) || ".xls".equals(extentionOfUnzipFile)) {
                            GenerateExcelTemplateUtil.convertToPdf(unZipFilePath, destDirectory);
                        }
                        else if(".pptx".equals(extentionOfUnzipFile) || ".ppt".equals(extentionOfUnzipFile)) {
                            GeneratePPTTemplateUtil.convertToPdf(unZipFilePath, destDirectory);
                        }
                        else if(".pdf".equals(extentionOfUnzipFile)) {
                        }
                        else if(isImage(unZipFilePath)){
                            GenerateWordTemplateUtil.convertImageToPdf(unZipFilePath, destDirectory);
                        }
                        else {
                            throw new ServiceException("暂不支持该格式文件预览！");
                        }

                        resultMap.put("attFileName", convertDisplayName);
                        resultMap.put("attInputStream", FileUtil.convertFileToBytes(destDirectory));
                    }
                }
            } catch (Exception ex) {
                throw new ServiceException(ex);
            } finally {
                if (os != null) {
                    os.close();
                    os = null;
                }
                if (is != null) {
                    is.close();
                    is = null;
                }
                if (ftpProcessor != null) {
                    ftpProcessor.close();
                }
                // 删除压缩文件
                FileUtil.deleteFile(tempZipFilePath);
                if (ParameterCache.getBooleanValue("CboAttchmentUnZipDelete", true)) {
                    // 删除解压后的文件
                    if (unZipFilePath != null) {
                        FileUtil.deleteFile(unZipFilePath);
                    }
                    // 删除临时目录
                    FileUtil.deleteDirectory(tempZipDirectoryName, true);
                } else {
                    // tempZipDirectoryName
                    resultMap.put("unZipFilePath", unZipFilePath);
                    resultMap.put("tempZipDirectoryName", tempZipDirectoryName);
                }
            }
        } catch (Exception ex) {
            throw new ServiceException(ex);
        }
    }


    /**
     * @param:         文件路径
     * @Description:    是否是图片 true-是 false-否
     * @Author:         mengmeng
     * @Date:           2021/9/22 19:42
     * @Version:        1.0
     */
    private static boolean isImage(String path) {
        File file = new File(path);
        if (file!=null && file.exists() && file.isFile()) {
            try {
                BufferedImage bi = ImageIO.read(file);
                if (bi != null) {
                    return true;
                }
            } catch (IOException e) {
                return false;
            }

        }
        return false;
    }
}
